#include "wchar.h"
#include "myIO.h"
#include "errno.h"
#include <stdio.h>
#include <time.h>
const int LONG_MAX = -2147483647;
const int LONG_MIN = -2147483648;

const float RAD = 0.35f;
const int dcm = 2;
const float DT = 5.0f;

bool MainInit::initAbout() {
    char buf[LEN_STR];
    if (!inData.readString(TITEL, buf)) {
        fprintf(log, "Cannot read %s\n", TITEL);
        return false;
    }
    strcpy(Info.ModelName, buf);

    if (!inData.readString(FName, buf)) {
        fprintf(log, "Cannot read %s\n", FName);
        return false;
    }
    strcpy(Info.Users[0].FName, buf);

    if (!inData.readString(LName, buf)) {
        fprintf(log, "Cannot read %s\n", LName);
        return false;
    }
    strcpy(Info.Users[0].LName, buf);
    return true;
}

bool MainInit::initSub() {
    char buf[LEN_STR];

    sub.TubeComp = 0;

    if (!inData.readString(SUBSTANCE, buf)) {
        fprintf(log, "Cannot read %s\n", SUBSTANCE);
        return true;
    }
    char* token = strtok(buf, ",");

    strcpy(sub.idName[0].CompName, token);
    sub.idName[0].ComponentID = 0;
    for (int c = 1; c < LEN_STR; c++) {
        token = strtok(NULL, ",");
        numMol = c;
        if (token == NULL) {
            sub.NUM_OF_COMPONENT = c;
            break;
        }
        if (strstr(token, "Tube") != 0) {
            sub.TubeComp++;
        }
        sub.NUM_OF_STATE[c] = 0;
        strcpy(sub.idName[c].CompName, token);
        sub.idName[c].ComponentID = c;
    }

    bool ok;
    float* compos = inData.readArray(COMPOS, sub.NUM_OF_COMPONENT - sub.TubeComp, &ok);
    if (!ok) {
        fprintf(log, "Cannot read %s\n", COMPOS);
        return true;
    }

    float summ = 0;
    for (int i = 0; i < sub.NUM_OF_COMPONENT - sub.TubeComp; i++) {
        summ += compos[i];
    }
    for (int i = 0; i < sub.NUM_OF_COMPONENT - sub.TubeComp; i++) {
        compos[i] = 100 * compos[i] / summ;
        molArr[i].Portion = compos[i];
    }

    delete[] compos;
    sub.nM = numMol - sub.TubeComp;
    return findSub();
}

bool MainInit::findSub() {
    char baseLine[256];
    char* end_chr;
    char* sPos;

    int rank;

    char cName[LEN_STR];
    int id = 0;
    float x = 0;
    float y = 0;
    float z = 0;

    fpos_t fp;
    fgetpos(mol, &fp);

    short chi = 0;

    char cntrl;

    char err2[LEN_STR] = " �������� ����������������� ����� ������ ����";
    char err3[LEN_STR] = "H� ������� ����� ��������� ����������� �������������� ";
    char err4[LEN_STR] = "������ � �������� �������� ";
    char err5[LEN_STR] = "������ �������� ������ �������� ";
    char err6[LEN_STR] = "�������������� ������ �������� ���������� ";

    bool isTube = false;

    for (int i = 0; i < sub.NUM_OF_COMPONENT;) {
        molArr[i].EfRank = 0;
        Tube->EfRank = 0;

        fsetpos(mol, &fp);
        chi = 0;
        while (fgets(baseLine, 256, mol) != NULL) {
            if (strstr(baseLine, "Potential") != 0) {
                break;
            }
            sPos = strstr(baseLine, sub.idName[i].CompName);
            if (sPos != NULL) {
                if (strstr(baseLine, "Tube") != 0) {
                    isTube = true;
                }

                chi++;
                strtok(baseLine, "\"");
                char* t = strtok(NULL, "\"");

                rank = strtod(t, &end_chr);
                molArr[i].rank = rank;

                if (!isTube) {
                    molArr[i].dCnt = new IForce *[rank];
                    for (int y_index = 0; y_index < rank; y_index++) {
                        molArr[i].dCnt[y_index] = new IForce[rank];
                        for (int z_index = 0; z_index < rank; z_index++) {
                            molArr[i].dCnt[y_index][z_index] = 0;
                        }
                    }

                    molArr[i].aCnt = new IForce **[rank];
                    for (int y_index = 0; y_index < rank; y_index++) {
                        molArr[i].aCnt[y_index] = new IForce *[rank];
                        for (int z_index = 0; z_index < rank; z_index++) {
                            molArr[i].aCnt[y_index][z_index] = new IForce[rank];
                        }
                    }
                }
                memcpy(molArr[i].mName, sub.idName[i].CompName, strlen(sub.idName[i].CompName) + 1);

                if (isTube) {
                    memcpy(Tube->mName, sub.idName[i].CompName, strlen(sub.idName[i].CompName) + 1);
                }

                for (int j = 0; j < rank; j++) {
                    if (!fgets(baseLine, 256, mol)) {
                        return true;
                    }
                    sscanf(baseLine, "ID|%i|CompName| %s |POS|%f|%f|%f|%c", &id, cName, &x, &y, &z, &cntrl);
                    if (cntrl != ';' && !isTube) {
                        strcat(err, err4);
                        strcat(err, molArr[i].mName);
                        strcat(err, ".\r\n");
                        return true;
                    } else {
                        cntrl = '0';
                    }

                    if (!isTube) {
                        molArr[i].molSrc[j].p = Vector3(x, y, z);
                    }
                    if (isTube) {
                        if (strstr(baseLine, "Temp") != 0) {
                            float T = 0;
                            float tau = 0;
                            sscanf(baseLine, "Temp|%f|%f|;", &T, &tau);
                            sub.TubeComp--;
                            Tube->Temp = T;
                            Tube->RelTime = tau;
                            Tube->rank = rank;
                            break;
                        } else {
                            Tube->EfRank++;
                        }
                    }
                    memcpy(molArr[i].molSrc[j].symbol, cName, strlen(cName) + 1);

                    if (j != 0) {
                        molArr[i].molSrc[j].privID = molArr[i].molSrc[j - 1].privID + 1;
                    } else {
                        molArr[i].molSrc[j].privID = 0;
                    }
                    molArr[i].EfRank++;

                    memcpy(&molArr[i].molCompos[molArr[i].EfRank - 1].CompName, &cName, strlen(cName) + 1);

                    if (isTube) {
                        memcpy(&Tube->molCompos[molArr[i].EfRank - 1].CompName, &cName, strlen(cName) + 1);
                        sub.TubeComp++;
                    }

                    for (int k = 0; k < j; k++) {
                        if (strcmp(cName, molArr[i].molCompos[k].CompName) == 0 && k != j) {
                            molArr[i].EfRank--;
                            molArr[i].molSrc[j].privID--;
                        }
                    }
                }
                while (fgets(baseLine, 256, mol) != 0) {
                    const char * p_ch;
                    p_ch = strstr(baseLine, "End");
                    if (p_ch != 0)
                        break;

                    p_ch = strstr(baseLine, "Dist");

                    if (p_ch != NULL) {
                        int pr[] = { 0, 0, 0 };
                        sscanf(baseLine, "Dist=|%i|%i|%i|%c", &pr[0], &pr[1], &pr[2], &cntrl);
                        if (cntrl != ';') {
                            strcat(err, err5);
                            strcat(err, molArr[i].mName);
                            strcat(err, ".\r\n");
                            return true;
                        } else {
                            cntrl = '0';
                        }

                        molArr[i].dCnt[pr[0]][pr[1]] = new IFr(pr[2]);
                    }
                }
            }
        }
        i++;
        if (chi > 1) {
            err = strcat(err, err2);
            err = strcat(err, sub.idName[i].CompName);
            return true;
        }
        if (chi == 0) {
            err = strcat(err, sub.idName[i].CompName);
            err = strcat(err, err2);
            return true;
        }
    }
    IDName exIdName[10];
    int numP = 0;
    for (int k = 0; k < sub.NUM_OF_COMPONENT; k++) {
        for (int i = 0; i < sub.NUM_OF_COMPONENT; i++) {
            if (strcmp(sub.idName[k].CompName, molArr[i].mName) == 0) {
                for (int j = 0; j < molArr[i].EfRank; j++) {
                    memcpy(exIdName[numP + j].CompName, molArr[i].molCompos[j].CompName, strlen(molArr[i].molCompos[j].CompName) + 1);
                    exIdName[numP + j].ComponentID = numP + j;
                    molArr[i].molCompos[j].ComponentID = numP + j;
                    if (sub.NUM_OF_COMPONENT - i == 1) {
                        Tube->molCompos[j].ComponentID = numP + j;
                    }
                }
                numP += molArr[i].EfRank;
            }
        }
    }
    sub.NUM_OF_COMPONENT = numP;
    memcpy(sub.idName, exIdName, 10 * sizeof(IDName));

    for (int q = 0; q < sub.nM; q++) {
        for (int qq = 0; qq < molArr[q].rank; qq++) {
            for (int h = 0; h < sub.NUM_OF_COMPONENT; h++) {
                if (strcmp(sub.idName[h].CompName, molArr[q].molSrc[qq].symbol) == 0) {
                    molArr[q].molSrc[qq].cId = sub.idName[h].ComponentID;
                    break;
                }
            }
        }
    }

    IForce dFunc;
    float read[4] = { 0, 0, 0, 0 };
    char Tp;
    int pID;
    while (fgets(baseLine, 256, mol) != NULL) {
        if (strstr(baseLine, "Dist") != 0) {
            sscanf(baseLine, "Dist|%i|%c|%f|%f|%f|%f|%c", &pID, &Tp, &read[0], &read[1], &read[2], &read[3], &cntrl);

            if (cntrl != ';') {
                strcat(err, err6);
                strcat(err, baseLine);
                strcat(err, "\r\n");
            } else {
                cntrl = '0';
            }

            dFunc = new IFr(read[0], read[1], read[2], read[3], Tp);
            for (int i = 0; i < sub.NUM_OF_COMPONENT - sub.TubeComp; i++) {
                for (int ii = 0; ii < molArr[i].rank; ii++) {
                    for (int jj = 0; jj < molArr[i].rank; jj++) {
                        if (molArr[i].dCnt[ii][jj] != 0 && molArr[i].dCnt[ii][jj]->pID == pID) {
                            molArr[i].dCnt[ii][jj] = dFunc;
                            molArr[i].dCnt[jj][ii] = dFunc;
                        }
                    }
                }
            }
        }
        if (strstr(baseLine, "End") != 0) {
            break;
        }
    }

    for (int i = 0; i < sub.NUM_OF_COMPONENT - sub.TubeComp; i++) {
        for (int ii = 0; ii < molArr[i].rank; ii++) {
            for (int jj = 0; jj < molArr[i].rank; jj++) {
                if (molArr[i].dCnt[ii][jj] != 0) {
                    if (molArr[i].dCnt[ii][jj]->getpTp() == 'N') {
                        strcat(err, err3);
                        strcat(err, molArr[i].mName);
                        strcat(err, ": ");
                        strcat(err, molArr[i].molCompos[molArr[i].molSrc[ii].privID].CompName);
                        strcat(err, " � ");
                        strcat(err, molArr[i].molCompos[molArr[i].molSrc[jj].privID].CompName);
                        return true;
                    }
                }
            }
        }
    }

    initPtnl();

    return false;
}

bool MainInit::initPtnl() {
    for (int i = 0; i < 10; ++i) {
        for (int j = 0; j < 10; ++j) {
            sub.ColFunc[i][j] = 0;
        }
    }

    char* Name = new char[LEN_STR];
    char* baseLine = new char[256];

    char ctrl;
    char err1[LEN_STR] = "������ ������ ���������� ";
    float read[4] = { 0, 0, 0, 0 };
    char Tp;

    fpos_t fp;
    fgetpos(interMol, &fp);

    for (int i = 0; i < sub.NUM_OF_COMPONENT + 1; i++) {
        for (int j = 0; j < sub.NUM_OF_COMPONENT + 1; j++) {
            fsetpos(interMol, &fp);
            while (fgets(baseLine, 256, interMol) != NULL) {
                if (strstr(baseLine, sub.idName[i].CompName) != 0 && strstr(baseLine, sub.idName[j].CompName)) {
                    sscanf(baseLine, "CompName| %s | %s |%c|%f|%f|%f|%f|%c\r\n", Name, Name, &Tp, &read[0], &read[1], &read[2], &read[3], &ctrl);
                    IForce iFr = NULL;
                    if (ctrl == ';') {
                        iFr = new IFr(read[0], read[1], read[2], read[3], Tp);
                    } else {
                        strcat(err, err1);
                        strcat(err, sub.idName[i].CompName);
                        strcat(err, "-");
                        strcat(err, sub.idName[j].CompName);
                        strcat(err, "\r\n");
                    }
                    sub.ColFunc[i][j] = iFr;
                }
            }
        }
    }

    FILE* MTable = fopen("./IO/MTable.txt", "r");

    if (!MTable) {
        return true;
    }

    FileReader readM(MTable);

    for (int i = 0; i < sub.NUM_OF_COMPONENT; i++) {
        bool ok;
        sub.idName[i].Mass = readM.readFloat(sub.idName[i].CompName, &ok);
        if (!ok) {
            return true;
        }
        if (i > sub.NUM_OF_COMPONENT - sub.TubeComp) {
            Tube->molCompos[i - sub.TubeComp].Mass = sub.idName[i].Mass;
        }

        printf("MASS_READ=%f\r\n", sub.idName[i].Mass);
    }

    FILE* TubeF = fopen("./IO/strTube.txt", "r");

    if (!TubeF) {
        return false;
    }

    FileReader tIn(TubeF);

    char buf[LEN_STR];
    tIn.readString("Name", buf);
    if (strcmp(buf, Tube->mName) != 0) {
        strcat(err, "����-�������� ������ �� ������");
        return true;
    }

    Tube->Rad = tIn.readFloat("Rad");
    Tube->Len = tIn.readFloat("Len");
    Tube->Vol = tIn.readFloat("Vol");
    Tube->cicl = ceil(tIn.readFloat("Cicl"));

    while (!(feof(TubeF) || strstr(baseLine, "<Struct>"))) {
        if (!fgets(baseLine, 256, TubeF)) {
            return true;
        }
    }
    int id;
    float x;
    float y;
    float z;
    char symbol[10];
    int ch = 0;
    for (int t = 0; t < Tube->rank; t++) {
        if (!fgets(baseLine, 256, TubeF)) {
            return true;
        }
        sscanf(baseLine, "ID|%i|CompName| %s |POS|%f|%f|%f|;", &id, symbol, &x, &y, &z);
        Tube->molSrc[ch].privID = id;
        Tube->molSrc[ch].p = Vector3(x, y, z);
        memcpy(Tube->molSrc[ch].symbol, symbol, strlen(symbol) + 1);
        for (int i = 0; i < Tube->EfRank; i++) {
            if (strcmp(Tube->molCompos[i].CompName, symbol) == 0) {
                Tube->molSrc[ch].cId = Tube->molCompos[i].ComponentID;
                break;
            }
        }
        ch++;
    }
    while (strstr(baseLine, "Dist") == 0) {
        if (!fgets(baseLine, 256, TubeF)) {
            return true;
        }
    }
    int II, JJ, KK;
    ch = 0;
    Tube->NumOfPair = Tube->rank * 6;
    Tube->dCnt = new IForce[Tube->NumOfPair];
    while ((strstr(baseLine, "End")) == 0) {
        sscanf(baseLine, "Dist|%i|%i|%i|;", &II, &JJ, &KK);
        Tube->dCnt[ch] = new IFr(II, JJ, KK);
        if (!fgets(baseLine, 256, TubeF)) {
            return true;
        }
        ch++;
    }
    Tube->NumOfPair = ch;

    while ((strstr(baseLine, "Dist")) == 0) {
        if (!fgets(baseLine, 256, TubeF)) {
            return true;
        }
    }

    while ((strstr(baseLine, "Dist")) != 0) {
        char t;
        int pid;
        float p1, p2, s, e;
        sscanf(baseLine, "Dist|%i|%c|%f|%f|%f|%f|;", &pid, &t, &p1, &p2, &s, &e);
        for (int zz = 0; zz < Tube->NumOfPair; zz++) {
            if (Tube->dCnt[zz]->pID == pid) {
                Tube->dCnt[zz]->Set(p1, p2, s, e, t);
            }
        }

        if (!fgets(baseLine, 256, TubeF)) {
            return true;
        }
    }

    delete[] baseLine;
    delete[] Name;

    return false;
}
void IFr::Set(float P1, float P2, float s, float e, char T) {
    eps = e;
    sigma = s;
    p1 = P1;
    p2 = P2;
    pTp = T;
}
MolDscr * MainInit::getMDscr() {
    return molArr;
}

char IFr::getpTp() const {
    return pTp;
}
IFr::IFr(float P1, float P2, float Sigma, float Eps, char T) :
    eps(Eps), sigma(Sigma), p1(P1), p2(P2), pTp(T) {
}

IFr::IFr(int pid) :
    pID(pid), pTp('N') {
}

IFr::IFr(int i, int j, int pid) :
    I(i), J(j), pID(pid), pTp('N') {
}

MainInit::MainInit(FILE* i, FILE* m, FILE* iM, FILE* l) :
    Tube(new TubeDscr()), inData(i), inMol(m), infoF(i), mol(m), interMol(iM), log(l), numMol(0) {
    err = new char[LEN_STR];
    char g[] = " :";
    memcpy(err, &g, 3);
}

/////////////////////////////

FileReader::FileReader(FILE* f) :
    _file(f) {
}
float FileReader::readFloat(const char* key, bool* ok) {
    char buf[LEN_STR];
    char* nextChar;
    if (!readString(key, buf)) {
        if (ok) {
            *ok = false;
        }
        return 0;
    }
    float result = strtod(buf, &nextChar);
    if (ok) {
        *ok = nextChar != buf;
    }
    return result;
}
float* FileReader::readArray(const char* key, int length, bool* ok) {
    char buf[LEN_STR];
    float* result = new float[length];
    if (!readString(key, buf)) {
        if (ok) {
            *ok = false;
        }
        return result;
    }
    if (ok) {
        *ok = true;
    }
    int i = 0;
    for (const char* token = strtok(buf, ","); token && i < length; token = strtok(NULL, ","), ++i) {
        char* nextChar;
        result[i] = strtod(token, &nextChar);
        if (ok) {
            *ok &= nextChar != token;
        }
    }
    if (ok) {
        *ok &= i == length;
    }
    return result;
}
bool FileReader::readString(const char* key, char buf[LEN_STR]) {
    char lineBuf[LEN_STR];
    rewind(_file);
    while (fgets(lineBuf, LEN_STR, _file)) {
        if (strstr(lineBuf, key)) {
            strtok(lineBuf, "\"");
            const char* string = strtok(NULL, "\"");
            strcpy(buf, string);
            return true;
        }
    }
    return false;
}
//////////////////////////////////////////////////////
Measurer::Measurer(info inf, SubListItem sub, TubeDscr * td, MolDscr * md, const Vector3& lb, const Vector3& rb) :
    tDscr(td), Sub(sub), Inf(inf), LB(lb), RB(rb), MAch(0), hX(dcm * RAD), hY(dcm * RAD), hZ(dcm * RAD), MaxF(0), MinF(0), netSizeX((rb.x - lb.x) / dcm / RAD + 1), netSizeY((rb.y - lb.y) / dcm / RAD + 1), netSizeZ((rb.z - lb.z) / dcm / RAD + 1)

{
    mDscr = new MolDscr[sub.nM];
    for (int i = 0; i < sub.nM; i++) {
        mDscr[i] = md[i];
    }

    mrsNet = new mrsCell **[netSizeZ];
    for (int k = 0; k < netSizeZ; k++) {
        mrsNet[k] = new mrsCell *[netSizeY];
        for (int j = 0; j < netSizeY; j++) {
            mrsNet[k][j] = new mrsCell[netSizeX];
            for (int i = 0; i < netSizeX; i++) {
                mrsNet[k][j][i].Ch = 0;
                for (int m = 0; m < MAP; m++) {
                    mrsNet[k][j][i].RoMA[m] = 0;
                    mrsNet[k][j][i].TempMA[m] = 0;
                    mrsNet[k][j][i].VelMA[m] = Vector3(0, 0, 0);
                }
            }
        }
    }

    HeadF = fopen("./IO/head.mdxml", "w");
    SubF = fopen("./IO/Substances.xml", "w");
    ChXML = fopen("./IO/Channels.xml", "w");
    ChF = fopen("./IO/Channel.chl", "w");
    FieldF = fopen("./IO/Field.fld", "w");
    tempF = fopen("./IO/temp.fld", "w");
}
;

void Measurer::closeField() {
    char baseLine[10 * LEN_STR];

    fclose(tempF);

    tempF = fopen("./IO/temp.fld", "r");
    fprintf(FieldF, "<Fields>\r\n");
    fprintf(FieldF, "<Field FieldID=\"1\" Type=\"ScalarInVolume\" Min=\"%.1f\" Max=\"%.1f\">\r\n", MinF, MaxF);

    while (!feof(tempF)) {
        if (!fgets(baseLine, 256, tempF)) {
            return;
        }
        if (feof(tempF)) {
            break;
        }
        fputs(baseLine, FieldF);
        fflush(FieldF);
    }
    fprintf(FieldF, "</Field>\r\n</Fields>\r\n");
    fflush(FieldF);
    fclose(FieldF);
    //remove("./IO/temp.fld");
}

void Measurer::outHead() {
    fprintf(HeadF, "<?xml version=\"1.0\" encoding=\"Windows-1251\"?>\r\n");
    tm* local;
    time_t t;

    t = time(NULL);
    local = localtime(&t);

    fprintf(HeadF, "<MolecularDynamics Name=\"%s\" Date=\"%s\" Language=\"ru\">\r\n", Inf.ModelName, asctime(local));
    fprintf(HeadF, "\t<Head>\r\n\t\t<User FirstName=\"%s\" MiddleName=\"%s\" LastName=\"%s\" />\r\n", Inf.Users[0].FName, "-", Inf.Users[0].LName);
    fprintf(HeadF, "\t\t<Target>\r\n \t\t</Target>\r\n");
    fprintf(HeadF, "\t</Head>\r\n");

    fprintf(HeadF, "\t<Body>\r\n\t\t<Substances>\r\n\t\t\t<AddSub SubID=\"1\" ScalFilter=\"Temperature\" Symbol=\"T(K)\"/>\r\n");
    fprintf(HeadF, "\t\t</Substances>\r\n\t\t<Dynamics File=\"dynamics.dyn\"/>\r\n");
    fprintf(HeadF, "\t\t<Channels>\r\n\t\t\t<AddChannel ChID=\"1\"/>\r\n\t\t</Channels>\r\n");
    fprintf(HeadF, "\t</Body>\r\n</MolecularDynamics>");
    fclose(HeadF);
}
void Measurer::outSub() {
    fprintf(SubF, "<?xml version=\"1.0\" encoding=\"Windows-1251\"?>\r\n");
    fprintf(SubF, "<Substances>\r\n");
    char subName[LEN_STR] = "";
    for (int i = 0; i < Sub.nM; i++) {
        strcat(subName, Sub.idName[i].CompName);
        if (Sub.nM - i > 1) {
            strcat(subName, " + ");
        }
    }

    unsigned int color[10];
    for (int i = 0; i < Sub.NUM_OF_COMPONENT; i++) {
        color[i] = 0xfafffa - 0xfafffa / Sub.NUM_OF_COMPONENT * i;
    }

    fprintf(SubF, "\t<Substance SubID=\"1\" Name=\"%s\" Mode=\"Atom\">\r\n", subName);
    fprintf(SubF, "\t\t<InfoFile File=\"subInfo.inf\"/>\r\n");
    for (int i = 0; i < Sub.NUM_OF_COMPONENT - Sub.TubeComp; i++) {
        fprintf(SubF, "\t\t<Component CompID=\"%i\" Name=\"%s\"  Color=\"#%.6x\">\r\n", i, mDscr[i].mName, color[i]);
        fprintf(SubF, "\t\t\t<State StateID=\"0\" Symbol=\"%c", mDscr[i].mName[0]);

        if (strlen(mDscr[i].mName) > 1) {
            fprintf(SubF, "%c\"/>\r\n", mDscr[i].mName[1]);
        } else {
            fprintf(SubF, "\"/>\r\n");
        }
        fprintf(SubF, "\t\t</Component>\r\n");
    }
    for (int i = 0; i < tDscr->EfRank; i++) {
        fprintf(SubF, "\t\t<Component CompID=\"%i\" Name=\"%s\"  Color=\"#%.6x\">\r\n", Sub.NUM_OF_COMPONENT - Sub.TubeComp + i, tDscr->molCompos[i].CompName, color[Sub.NUM_OF_COMPONENT - Sub.TubeComp + i]);
        fprintf(SubF, "\t\t\t<State StateID=\"0\" Symbol=\"%c", tDscr->molCompos[i].CompName[0]);
        if (strlen(tDscr->molCompos[i].CompName) > 1) {
            fprintf(SubF, "%c\"/>\r\n", tDscr->molCompos[i].CompName[1]);
        } else {
            fprintf(SubF, "\"/>\r\n");
        }

        fprintf(SubF, "\t\t</Component>\r\n");
    }
    fprintf(SubF, "\t</Substance>\r\n");
    fprintf(SubF, "</Substances>");

    fclose(SubF);
}
;

void Measurer::outChl() {
    fprintf(ChXML, "<?xml version=\"1.0\" encoding=\"Windows-1251\"?>\r\n");
    fprintf(ChXML, "<Channels>\r\n\t<Channel ChID=\"1\" Name=\"%s\" Type=\"Tube0\" Color=\"#00e7ff\">\r\n", tDscr->mName);
    fprintf(ChXML, "\t\t<ChannelFile File=\"Channel.chl\"/>\r\n");

    fprintf(ChXML, "\t</Channel>\r\n");
    fprintf(ChXML, "</Channels>");

    fprintf(ChF, "<Channels>\r\n");
    fprintf(ChF, "<Channel ChID=\"1\" Type=\"Tube0\">\r\n");
    fprintf(ChF, "AXIS|1.00|0.00|0.00|;\r\n");
    fprintf(ChF, "POS|2.0|0.00|0.00|;\r\n");
    fprintf(ChF, "H|%.3f|L|%.2f|R|%.2f|;\r\n", Sub.ColFunc[tDscr->molCompos[0].ComponentID][tDscr->molCompos[0].ComponentID]->Potential(0, 'R'), tDscr->Len, tDscr->Rad);
    fprintf(ChF, "</Channel>\r\n</Channels>");
    fclose(ChF);
    fclose(ChXML);
}

void Measurer::outField(int ITER) {
    fprintf(tempF, "<Iteration Num_of_iter=\"%i\">\r\n", ITER);

    for (int k = 0; k < netSizeZ; k++) {
        fprintf(tempF, "|%.2f|", k * dcm * RAD + LB.z + RAD / 2 * dcm);
        for (int i = 0; i < netSizeX; i++) {
            fprintf(tempF, "%.2f|", i * dcm * RAD + LB.x + RAD / 2 * dcm);
        }
        fprintf(tempF, "\r\n");
        for (int j = 0; j < netSizeY; j++) {
            fprintf(tempF, "|%.2f|", j * dcm * RAD + LB.y + RAD / 2 * dcm);

            for (int i = 0; i < netSizeX; i++) {
                float out = 0;
                for (int m = 0; m < MAP; m++) {
                    out = out + mrsNet[k][j][i].RoMA[m] / MAP / RAD / RAD / RAD / dcm / dcm / dcm / 1e-27;
                }
                fflush(tempF);
                fprintf(tempF, "%.2f|", out);
                fflush(tempF);
            }
            if (j < netSizeY - 1) {
                fprintf(tempF, "\r\n");
            } else {
                fprintf(tempF, ";\r\n");
            }
        }
        if (k < netSizeZ - 1) {
            fprintf(tempF, "\r\n");
        }
    }

    fprintf(tempF, "</Iteration>\r\n");
    fflush(tempF);
}

void Measurer::Measurement(toVisual * sys, int end) {
    for (int k = 0; k < netSizeZ; k++) {
        for (int j = 0; j < netSizeY; j++) {
            for (int i = 0; i < netSizeX; i++) {
                mrsNet[k][j][i].RoMA[MAch % MAP] = 0;
            }
        }
    }

    int I, J, K;
    for (int q = 0; q < end; q++) {
        Vector3 sPos = sys[q].pos - LB;
        I = sPos.x / hX;
        J = sPos.y / hY;
        K = sPos.z / hZ;
        if (K >= 0 && K < netSizeZ && J >= 0 && J < netSizeY && I >= 0 && I < netSizeX) {
            mrsNet[K][J][I].Ch++;
            mrsNet[K][J][I].RoMA[MAch % MAP] += sys[q].M * 1e-9f;
        }
    }

    for (int k = 0; k < netSizeZ; k++) {
        for (int j = 0; j < netSizeY; j++) {
            for (int i = 0; i < netSizeX; i++) {
                if (mrsNet[k][j][i].RoMA[MAch % MAP] > 0 && mrsNet[k][j][i].Ch > 0) {
                    mrsNet[k][j][i].RoMA[MAch % MAP] = mrsNet[k][j][i].RoMA[MAch % MAP];
                }
            }
        }
    }

    MAch++;
}

